package com.campus.help.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.help.common.PageResult;
import com.campus.help.dto.BroadcastMessageDTO;
import com.campus.help.dto.MessageDTO;
import com.campus.help.entity.Message;
import com.campus.help.entity.Student;
import com.campus.help.mapper.MessageMapper;
import com.campus.help.mapper.StudentMapper;
import com.campus.help.service.MessageService;
import com.campus.help.vo.MessageVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.HashMap;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 消息服务实现类（简化版）
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
    
    private final MessageMapper messageMapper;
    private final StudentMapper studentMapper;
    
    @Override
    public PageResult<MessageVO> getUserMessages(Long userId, String type, int page, int size) {
        try {
            long offset = (page - 1) * size;
            List<MessageVO> records = messageMapper.selectUserMessages(userId, type, offset, (long) size);
            Long total = messageMapper.countUserMessages(userId, type);
            
            // 格式化时间显示
            records.forEach(this::formatMessageTime);
            
            return new PageResult<>((long) page, (long) size, total, records);
        } catch (Exception e) {
            log.error("获取用户消息失败", e);
            return new PageResult<>((long) page, (long) size, 0L, new ArrayList<>());
        }
    }
    
    @Override
    public Map<String, Integer> getUnreadMessageStats(Long userId) {
        try {
            Map<String, Object> stats = messageMapper.getUnreadStatsByUserId(userId);
            Map<String, Integer> result = new HashMap<>();
            
            // 处理查询结果，转换为Integer类型
            result.put("all", convertToInt(stats.get("all_count")));
            result.put("system", convertToInt(stats.get("system_count")));
            result.put("labor", convertToInt(stats.get("labor_count")));
            result.put("order", convertToInt(stats.get("order_count")));
            result.put("broadcast", convertToInt(stats.get("broadcast_count")));
            
            return result;
        } catch (Exception e) {
            log.error("获取未读消息统计失败", e);
            // 返回默认值
            Map<String, Integer> result = new HashMap<>();
            result.put("all", 0);
            result.put("system", 0);
            result.put("labor", 0);
            result.put("order", 0);
            result.put("broadcast", 0);
            return result;
        }
    }
    
    @Override
    @Transactional
    public boolean sendMessage(MessageDTO messageDTO, Long senderId, String senderName) {
        try {
            Message message = new Message();
            message.setType(messageDTO.getType());
            message.setTitle(messageDTO.getTitle());
            message.setContent(messageDTO.getContent());
            message.setSenderId(senderId);
            message.setSenderName(senderName);
            message.setReceiverId(messageDTO.getReceiverId());
            message.setRelatedId(messageDTO.getRelatedId());
            message.setRelatedType(messageDTO.getRelatedType());
            message.setIsRead(0);
            message.setPriority(messageDTO.getPriority() != null ? messageDTO.getPriority() : 1);
            message.setExtraData(messageDTO.getExtraData());
            
            return this.save(message);
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional
    public boolean broadcastMessage(BroadcastMessageDTO broadcastDTO, Long senderId, String senderName) {
        try {
            List<Long> targetUserIds = getTargetUserIds(broadcastDTO);
            
            if (targetUserIds.isEmpty()) {
                log.warn("广播消息没有目标用户");
                return false;
            }
            
            List<Message> messages = new ArrayList<>();
            for (Long userId : targetUserIds) {
                Message message = new Message();
                message.setType("broadcast");
                message.setTitle(broadcastDTO.getTitle());
                message.setContent(broadcastDTO.getContent());
                message.setSenderId(senderId);
                message.setSenderName(senderName);
                message.setReceiverId(userId);
                message.setIsRead(0);
                message.setPriority(broadcastDTO.getPriority() != null ? broadcastDTO.getPriority() : 1);
                messages.add(message);
            }
            
            // 使用自定义的批量插入方法
            return messageMapper.batchInsert(messages) > 0;
        } catch (Exception e) {
            log.error("广播消息失败", e);
            return false;
        }
    }
    
    @Override
    public boolean markMessageAsRead(Long userId, Long messageId) {
        try {
            return messageMapper.markAsRead(messageId, userId) > 0;
        } catch (Exception e) {
            log.error("标记消息已读失败", e);
            return false;
        }
    }
    
    @Override
    public boolean markMessagesAsRead(Long userId, List<Long> messageIds) {
        try {
            int updated = 0;
            for (Long messageId : messageIds) {
                updated += messageMapper.markAsRead(messageId, userId);
            }
            return updated > 0;
        } catch (Exception e) {
            log.error("批量标记消息已读失败", e);
            return false;
        }
    }
    
    @Override
    public boolean markAllMessagesAsRead(Long userId, String type) {
        try {
            return messageMapper.markAllAsRead(userId, type) > 0;
        } catch (Exception e) {
            log.error("标记所有消息已读失败", e);
            return false;
        }
    }
    
    @Override
    public boolean deleteMessages(Long userId, List<Long> messageIds) {
        try {
            int deleted = 0;
            for (Long messageId : messageIds) {
                deleted += messageMapper.deleteMessage(messageId, userId);
            }
            return deleted > 0;
        } catch (Exception e) {
            log.error("删除消息失败", e);
            return false;
        }
    }
    
    @Override
    public boolean sendLaborReviewMessage(Long applicantId, Long laborId, String laborTitle, 
                                          String reviewResult, String reviewNote, Long reviewerId, String reviewerName) {
        try {
            Message message = new Message();
            message.setType("labor");
            
            if ("approved".equals(reviewResult)) {
                message.setTitle("劳务申请通过");
                message.setContent(String.format("恭喜！您申请的劳务任务「%s」已通过审核。", laborTitle));
            } else {
                message.setTitle("劳务申请被拒绝");
                message.setContent(String.format("很抱歉，您申请的劳务任务「%s」未通过审核。", laborTitle));
            }
            
            if (reviewNote != null && !reviewNote.trim().isEmpty()) {
                message.setContent(message.getContent() + "\n\n" + reviewNote);
            }
            
            message.setSenderId(reviewerId);
            message.setSenderName(reviewerName);
            message.setReceiverId(applicantId);
            message.setRelatedId(laborId);
            message.setRelatedType("labor");
            message.setIsRead(0);
            message.setPriority(2); // 中等优先级
            
            return this.save(message);
        } catch (Exception e) {
            log.error("发送劳务审核消息失败", e);
            return false;
        }
    }
    
    @Override
    public boolean sendLaborApplicationMessage(Long publisherId, Long laborId, String laborTitle,
                                               String applicantName, Long applicantId) {
        try {
            Message message = new Message();
            message.setType("labor");
            message.setTitle("新的劳务申请");
            message.setContent(String.format("用户「%s」申请了您发布的劳务任务「%s」，请及时处理。", applicantName, laborTitle));
            message.setSenderId(applicantId);
            message.setSenderName(applicantName);
            message.setReceiverId(publisherId);
            message.setRelatedId(laborId);
            message.setRelatedType("labor");
            message.setIsRead(0);
            message.setPriority(2); // 中等优先级
            
            return this.save(message);
        } catch (Exception e) {
            log.error("发送劳务申请消息失败", e);
            return false;
        }
    }
    
    @Override
    public boolean sendSystemMessage(String title, String content, Long receiverId) {
        try {
            Message message = new Message();
            message.setType("system");
            message.setTitle(title);
            message.setContent(content);
            message.setSenderId(0L); // 系统消息
            message.setSenderName("系统");
            message.setReceiverId(receiverId);
            message.setIsRead(0);
            message.setPriority(1); // 低优先级
            
            return this.save(message);
        } catch (Exception e) {
            log.error("发送系统消息失败", e);
            return false;
        }
    }
    
    @Override
    public MessageVO getMessageDetail(Long messageId, Long userId) {
        try {
            QueryWrapper<Message> wrapper = new QueryWrapper<>();
            wrapper.eq("id", messageId)
                   .eq("receiver_id", userId)
                   .eq("deleted", 0);
            
            Message message = this.getOne(wrapper);
            if (message == null) {
                return null;
            }
            
            MessageVO messageVO = convertToVO(message);
            formatMessageTime(messageVO);
            
            // 标记为已读
            if (message.getIsRead() == 0) {
                markMessageAsRead(userId, messageId);
            }
            
            return messageVO;
        } catch (Exception e) {
            log.error("获取消息详情失败", e);
            return null;
        }
    }
    
    /**
     * 获取目标用户ID列表
     */
    private List<Long> getTargetUserIds(BroadcastMessageDTO broadcastDTO) {
        List<Long> userIds = new ArrayList<>();
        
        try {
            switch (broadcastDTO.getTargetType()) {
                case "all":
                    // 获取所有学生
                    QueryWrapper<Student> allWrapper = new QueryWrapper<>();
                    allWrapper.select("id").eq("deleted", 0);
                    userIds = studentMapper.selectList(allWrapper).stream()
                            .map(Student::getId)
                            .collect(Collectors.toList());
                    break;
                    
                case "school":
                    // 获取指定学校的学生
                    if (broadcastDTO.getTargetSchoolIds() != null && !broadcastDTO.getTargetSchoolIds().isEmpty()) {
                        QueryWrapper<Student> schoolWrapper = new QueryWrapper<>();
                        schoolWrapper.select("id").in("school_id", broadcastDTO.getTargetSchoolIds()).eq("deleted", 0);
                        userIds = studentMapper.selectList(schoolWrapper).stream()
                                .map(Student::getId)
                                .collect(Collectors.toList());
                    }
                    break;
                    
                case "user":
                    // 指定用户
                    if (broadcastDTO.getTargetUserIds() != null) {
                        userIds = broadcastDTO.getTargetUserIds();
                    }
                    break;
            }
        } catch (Exception e) {
            log.error("获取目标用户ID列表失败", e);
        }
        
        return userIds;
    }
    
    /**
     * 转换数值类型为Integer
     */
    private Integer convertToInt(Object value) {
        if (value == null) {
            return 0;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (Exception e) {
            return 0;
        }
    }
    
    /**
     * 格式化消息时间显示
     */
    private void formatMessageTime(MessageVO messageVO) {
        if (messageVO.getCreateTime() == null) {
            messageVO.setTimeDisplay("未知");
            return;
        }
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime createTime = messageVO.getCreateTime();
        
        long minutes = java.time.Duration.between(createTime, now).toMinutes();
        long hours = minutes / 60;
        long days = hours / 24;
        
        if (minutes < 1) {
            messageVO.setTimeDisplay("刚刚");
        } else if (minutes < 60) {
            messageVO.setTimeDisplay(minutes + "分钟前");
        } else if (hours < 24) {
            messageVO.setTimeDisplay(hours + "小时前");
        } else if (days < 7) {
            messageVO.setTimeDisplay(days + "天前");
        } else {
            messageVO.setTimeDisplay(createTime.format(DateTimeFormatter.ofPattern("MM-dd HH:mm")));
        }
        
        // 设置预览文本
        if (messageVO.getContent() != null && messageVO.getContent().length() > 50) {
            messageVO.setPreview(messageVO.getContent().substring(0, 50) + "...");
        } else {
            messageVO.setPreview(messageVO.getContent());
        }
    }
    
    @Override
    public PageResult<MessageVO> getAdminMessages(int page, int size, String type, String keyword, String startDate, String endDate) {
        try {
            QueryWrapper<Message> wrapper = new QueryWrapper<>();
            wrapper.eq("deleted", 0);
            
            // 类型筛选
            if (type != null && !type.trim().isEmpty()) {
                wrapper.eq("type", type);
            }
            
            // 关键词搜索
            if (keyword != null && !keyword.trim().isEmpty()) {
                wrapper.and(w -> w.like("title", keyword).or().like("content", keyword));
            }
            
            // 日期范围筛选
            if (startDate != null && !startDate.trim().isEmpty()) {
                wrapper.ge("create_time", startDate + " 00:00:00");
            }
            if (endDate != null && !endDate.trim().isEmpty()) {
                wrapper.le("create_time", endDate + " 23:59:59");
            }
            
            wrapper.orderByDesc("create_time");
            
            Page<Message> pageParam = new Page<>(page, size);
            Page<Message> result = this.page(pageParam, wrapper);
            
            List<MessageVO> voList = result.getRecords().stream()
                    .map(this::convertToVO)
                    .collect(Collectors.toList());
            
            return new PageResult<>((long) page, (long) size, result.getTotal(), voList);
        } catch (Exception e) {
            log.error("查询管理员消息失败", e);
            return new PageResult<>((long) page, (long) size, 0L, new ArrayList<>());
        }
    }
    
    @Override
    public Map<String, Object> getMessageStats() {
        try {
            Map<String, Object> stats = new HashMap<>();
            
            QueryWrapper<Message> wrapper = new QueryWrapper<>();
            wrapper.eq("deleted", 0);
            
            // 总消息数
            long totalMessages = this.count(wrapper);
            stats.put("totalMessages", totalMessages);
            
            // 未读消息数
            QueryWrapper<Message> unreadWrapper = new QueryWrapper<>();
            unreadWrapper.eq("deleted", 0).eq("is_read", 0);
            long unreadMessages = this.count(unreadWrapper);
            stats.put("unreadMessages", unreadMessages);
            
            // 群发消息数
            QueryWrapper<Message> broadcastWrapper = new QueryWrapper<>();
            broadcastWrapper.eq("deleted", 0).eq("type", "broadcast");
            long broadcastMessages = this.count(broadcastWrapper);
            stats.put("broadcastMessages", broadcastMessages);
            
            // 系统消息数
            QueryWrapper<Message> systemWrapper = new QueryWrapper<>();
            systemWrapper.eq("deleted", 0).eq("type", "system");
            long systemMessages = this.count(systemWrapper);
            stats.put("systemMessages", systemMessages);
            
            return stats;
        } catch (Exception e) {
            log.error("获取消息统计失败", e);
            Map<String, Object> defaultStats = new HashMap<>();
            defaultStats.put("totalMessages", 0);
            defaultStats.put("unreadMessages", 0);
            defaultStats.put("broadcastMessages", 0);
            defaultStats.put("systemMessages", 0);
            return defaultStats;
        }
    }
    
    @Override
    public boolean deleteMessage(Long messageId) {
        try {
            UpdateWrapper<Message> wrapper = new UpdateWrapper<>();
            wrapper.eq("id", messageId);
            wrapper.set("deleted", 1);
            wrapper.set("update_time", LocalDateTime.now());
            return this.update(wrapper);
        } catch (Exception e) {
            log.error("删除消息失败", e);
            return false;
        }
    }
    
    @Override
    public boolean batchDeleteMessages(List<Long> messageIds) {
        try {
            if (messageIds == null || messageIds.isEmpty()) {
                return true;
            }
            
            UpdateWrapper<Message> wrapper = new UpdateWrapper<>();
            wrapper.in("id", messageIds);
            wrapper.set("deleted", 1);
            wrapper.set("update_time", LocalDateTime.now());
            return this.update(wrapper);
        } catch (Exception e) {
            log.error("批量删除消息失败", e);
            return false;
        }
    }

    /**
     * 转换为VO对象
     */
    private MessageVO convertToVO(Message message) {
        MessageVO vo = new MessageVO();
        vo.setId(message.getId());
        vo.setType(message.getType());
        vo.setTitle(message.getTitle());
        vo.setContent(message.getContent());
        vo.setSenderId(message.getSenderId());
        vo.setSenderName(message.getSenderName());
        vo.setReceiverId(message.getReceiverId());
        vo.setRelatedId(message.getRelatedId());
        vo.setRelatedType(message.getRelatedType());
        vo.setIsRead(message.getIsRead());
        vo.setPriority(message.getPriority());
        vo.setExtraData(message.getExtraData());
        vo.setCreateTime(message.getCreateTime());
        return vo;
    }
}